package com.gzx.spring.apis.service;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.date.DateUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gzx.risk.core.apis.context.ApiContext;
import com.gzx.risk.core.apis.result.RiskResult;
import com.gzx.risk.core.apis.result.huarong.HuarongC9004;
import com.gzx.risk.core.apis.result.huarong.HuarongC9005;
import com.gzx.risk.core.apis.result.huarong.HuarongR9003;
import com.gzx.risk.core.enums.AuthStatus;
import com.gzx.risk.core.enums.RiskNodes;
import com.gzx.risk.core.pojo.CreditAuthInfo;
import com.gzx.risk.core.pojo.UserInfo;
import com.gzx.risk.core.utils.FileDownloadUtils;
import com.gzx.risk.core.utils.ImageUtil;
import com.gzx.risk.core.vo.credit.C9004;
import com.gzx.spring.apis.utils.HuarongUtil;
import com.gzx.spring.apis.utils.RequestUtil;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.File;
import java.time.LocalDateTime;
import java.util.Date;

/**
 * 华融资信风控业务api服务
 */
@Slf4j
@Service
public class HuarongService {
    @Value("${apis.huarong.desKey}")
    private String desKey;                      // des盐key
    @Value("${apis.huarong.md5Key}")
    private String md5Key;                      // md5Key
    @Value("${apis.huarong.postUrlBase}")
    private String post_url_base;               // 征信查询请求地址
    @Value("${apis.huarong.merchantId}")
    private String merchantId;                  // 机构编号
    @Value("${apis.huarong.env}")
    private String env;
    private String privateKeyBase64; // rsa私钥
    private String publicKeyBase64; // rsa公钥

    @PostConstruct
    public void initKeys() {
        try {
            this.privateKeyBase64 = load("/huarong/" + env + "/privateKey.txt");
            this.publicKeyBase64 = load("/huarong/" + env + "/publicKey.txt");
        } catch (Exception e) {
            throw new RuntimeException("加载 " + env + " 环境的密钥失败，请检查文件路径和内容。", e);
        }
    }

    private String load(String name) {
        try {
            return IOUtils.toString(HuarongService.class.getResourceAsStream(name), "UTF-8");
        } catch (Exception e) {
            return "";
        }
    }

    @Resource
    private ObjectMapper objectMapper;

    public String C9004(C9004 c9004) throws Exception {
        if ("debug".equals(env)) {
            return ApiExec.loadJson("/debug/huarong/C9004Resp");
        }else {
            HuarongUtil huarongUtil = new HuarongUtil().publicKeyBase64(publicKeyBase64).privateKeyBase64(privateKeyBase64)
                    .merchantId(merchantId).post_url_base(post_url_base).desKey(desKey).md5Key(md5Key);
            return huarongUtil.C9004(c9004);
        }
    }

    public String C9005(String serialNumber) throws Exception {
        if ("debug".equals(env)) {
            return ApiExec.loadJson("/debug/huarong/C9005");
        }else {
            HuarongUtil huarongUtil = new HuarongUtil().publicKeyBase64(publicKeyBase64).privateKeyBase64(privateKeyBase64)
                    .merchantId(merchantId).post_url_base(post_url_base).desKey(desKey).md5Key(md5Key);
            return huarongUtil.C9005(serialNumber);
        }
    }

    public String R9003(String serialNumber) throws Exception {
        if ("debug".equals(env)) {
            return ApiExec.loadJson("/debug/huarong/R9003");
        }else {
            HuarongUtil huarongUtil = new HuarongUtil().publicKeyBase64(publicKeyBase64).privateKeyBase64(privateKeyBase64)
                    .merchantId(merchantId).post_url_base(post_url_base).desKey(desKey).md5Key(md5Key);
            return huarongUtil.R9003(serialNumber);
        }
    }

    public RiskResult C9004(String groupName, ApiContext ctx) throws Exception {
        UserInfo userInfo = ctx.getUserInfo();
        CreditAuthInfo creditAuthInfo = userInfo.getCreditAuthInfo();

        String apiName = "huarong_C9004";
        C9004 c9004 = buildUserAuthInfo(ctx.getUserInfo());
        String json = this.C9004(c9004);
        HuarongC9004 obj = objectMapper.readValue(json, HuarongC9004.class);
        obj.setGroupName(groupName);
        obj.setDataName(apiName);
        ctx.add(obj);
        userInfo.setRiskNode(RiskNodes.RISK_ONE.getCode());
        // 将结果添加到上下文中
        if (obj.isSuccess()) {
            creditAuthInfo.setSerialNumber(obj.getData().get("serialNumber").toString());
            creditAuthInfo.setAuthorizationStatus(AuthStatus.SUBMIT.getCode());
            creditAuthInfo.setAuthSubmitDatetime(LocalDateTime.now());
            creditAuthInfo.setAuthExpireDatetime(LocalDateTime.now().plusDays(30));
        } else {
            creditAuthInfo.setAuthorizationStatus(AuthStatus.NOT_SUBMIT.getCode());
            log.warn("{},code:{},msg:{}", apiName, obj.getCode(), obj.getMessage());
        }
        return obj;
    }

    public RiskResult C9005(String groupName, ApiContext ctx) throws Exception {
        UserInfo userInfo = ctx.getUserInfo();
        CreditAuthInfo creditAuthInfo = userInfo.getCreditAuthInfo();

        String apiName = "huarong_C9005";
        String json = this.C9005(creditAuthInfo.getSerialNumber());
        HuarongC9005 obj = objectMapper.readValue(json, HuarongC9005.class);
        obj.setGroupName(groupName);
        obj.setDataName(apiName);
        ctx.add(obj);
        userInfo.setRiskNode(RiskNodes.RISK_TWO.getCode());
        if (obj.isSuccess()) {
            creditAuthInfo.setAuthorizationStatus(AuthStatus.AUTH_SUCCESS.getCode());
        }else if (obj.isWaiting()){
            userInfo.setIsB0013(Boolean.TRUE);
        }else {
            creditAuthInfo.setAuthorizationStatus(AuthStatus.AUTH_FAILED.getCode());
            log.warn("{},code:{},msg:{}", apiName, obj.getCode(), obj.getMessage());
        }
        return obj;
    }

    public RiskResult R9003(String groupName, ApiContext ctx) throws Exception {
        UserInfo userInfo = ctx.getUserInfo();
        CreditAuthInfo creditAuthInfo = userInfo.getCreditAuthInfo();

        String apiName = "huarong_R9003";
        String json = "";
        if (StringUtils.isBlank(creditAuthInfo.getCreditInfo())) {
            json = this.R9003(creditAuthInfo.getSerialNumber());
        }else {
            json = creditAuthInfo.getCreditInfo();
        }

        HuarongR9003 obj = objectMapper.readValue(json, HuarongR9003.class);
        obj.setGroupName(groupName);
        obj.setDataName(apiName);
        userInfo.setRiskNode(RiskNodes.RISK_TWO.getCode());
        // 将结果添加到上下文中
        if (obj.isSuccess()) {
            ctx.add(obj);
            creditAuthInfo.setAuthorizationStatus(AuthStatus.AUTH_SUCCESS.getCode());
            creditAuthInfo.setCreditInfo(json);
        } else {
            creditAuthInfo.setAuthorizationStatus(AuthStatus.AUTH_FAILED.getCode());
            log.warn("{},code:{},msg:{}", apiName, obj.getCode(), obj.getMessage());
        }
        return obj;
    }

    private C9004 buildUserAuthInfo(UserInfo userInfo) throws Exception {
        CreditAuthInfo creditAuthInfo = userInfo.getCreditAuthInfo();
        C9004 c9004 = new C9004();
        c9004.setRequestNo(RequestUtil.getRequestNo());
        c9004.setQueryName(userInfo.getName());
        c9004.setQueryIdNo(userInfo.getId());
        c9004.setQueryPhone(userInfo.getPhone());
        c9004.setVeriFaceTime(DateUtil.now());
        c9004.setAuthTime(DateUtil.now());
        File mergeFile = ImageUtil.mergeTwoFromInternet(
                FileDownloadUtils.downloadFile(creditAuthInfo.getIdCardFrontUrl()),
                FileDownloadUtils.downloadFile(creditAuthInfo.getIdCardBackUrl()),
                "idCardFile");
        c9004.setIdCardFile(Base64.encode(ImageUtil.scaleImages(mergeFile, "反面正面")));
        c9004.setOtherAuthFile(Base64.encode(FileDownloadUtils.downloadFile(creditAuthInfo.getPersonVerifyUrl())));
        c9004.setCaFile(Base64.encode(FileDownloadUtils.downloadFile(creditAuthInfo.getCaAuthUrl())));
        File file = FileDownloadUtils.downloadPDFFile(creditAuthInfo.getGuaranteeApplyUrl());
        c9004.setOtherFile(Base64.encode(FileDownloadUtils.zipTempFile(file)));
        c9004.setQueryDate(DateUtil.format(new Date(), "yyyyMMdd"));
        return c9004;
    }
}
